<?php
/* 支付宝支付方式插件 */
class AlipayPayment extends BasePayment{
    /* 支付宝网关 */

    var $_gateway = 'https://mapi.alipay.com/gateway.do';
	
    var $_code = 'alipay';
    var $_pid = '';
    var $asign_mobile = ''; //发给手机端进行验证组合

    /* 获取支付表单
     * @param array $order_info  待支付的订单信息，必须包含总费用及唯一外部交易号
     */
    function get_payform($order_sn_main,$money){
        $action = '_' . $this->_code;
        $service = $this->_config['alipay_service'];
        $agent = 'C4335319945672464113';
        $params = array(
            /* 基本信息 */
            'agent' => $agent,
            'service' => $service,
            'partner' => $this->_config['alipay_partner'],
            '_input_charset' => "utf-8",
            'notify_url' => $this->_create_notify_url($order_sn_main,"notify".$action),
            'return_url' => $this->_create_return_url($order_sn_main,"return".$action),
            /* 业务参数 */
            'subject' => $this->_get_subject($order_sn_main),
            //订单ID由不属签名验证的一部分，所以有可能被客户自行修改，所以在接收网关通知时要验证指定的订单ID的外部交易号是否与网关传过来的一致
            'out_trade_no' => $this->_get_trade_sn($order_sn_main,$money),
            'total_fee' => $money,//应付总价
            'payment_type' => 1,
            /* 物流参数 */
            'logistics_type' => 'EXPRESS',
            'logistics_fee' => 0,
            'logistics_payment' => 'BUYER_PAY_AFTER_RECEIVE',
            /* 买卖双方信息 */
            'seller_id' => $this->_config['alipay_partner']
        );
        if($this->_info["bank_code"]){
            $params["defaultbank"]=$this->_info["bank_code"];
            $params["paymethod"]="bankPay";
        }
        $params['sign'] = $this->_get_sign($params);
        $params['sign_type'] = 'MD5';
        return $this->_create_payform('GET',$params);
    }

    /* 返回通知结果 */
    function verify_notify($notify,$paysign,$strict = false){
        /* 验证来路是否可信 */
        if($strict){
            /* 严格验证 */
            $verify_result = $this->_query_notify($notify['notify_id']);
            if(!$verify_result){
                /* 来路不可信 */
                $this->_error('notify_unauthentic');
                return false;
            }
        }
        /* 验证通知是否可信 */
        $sign_result = $this->_verify_sign($notify);
        if(!$sign_result){
            /* 若本地签名与网关签名不一致，说明签名不可信 */
            $this->_error('sign_inconsistent');
            return false;
        }
        if($paysign['out_order_sn'] != $notify['out_trade_no']){
            /* 通知中的订单与欲改变的订单不一致 */
            $this->_error('order_inconsistent');
            return false;
        }
        if($paysign['money'] != $notify['total_fee']){
            /* 支付的金额与实际金额不一致 */
            $this->_error('price_inconsistent');
            return false;
        }
        return true;
    }

    /* 查询通知是否有效 */
    function _query_notify($notify_id){
        $query_url = "http://notify.alipay.com/trade/notify_query.do?partner={$this->_config['alipay_partner']}&notify_id={$notify_id}";
        return tcz_fopen($query_url,60);
    }

    /* 获取签名字符串 */
    function _get_sign($params){
        //var_dump($params);
        /* 去除不参与签名的数据 */
        unset($params['sign'],$params['sign_type'],$params['main'],$params['c'],$params['a']);
        /* 排序 */
        ksort($params);
        reset($params);
        
        $sign = '';
        foreach($params AS $key => $value){
            if($value === ''){
                continue;
            }
            $sign .= "{$key}={$value}&";
        }
        $this->asign_mobile = substr($sign,0,-1) . $this->_config['alipay_key'];
        return md5(substr($sign,0,-1) . $this->_config['alipay_key']);
    }

    /* 验证签名是否可信 */
    function _verify_sign($notify){
        $local_sign = $this->_get_sign($notify);
        return ($local_sign == $notify['sign']);
    }

    /* 手机端验证签名是否可信 */
    function _verify_sign_mobile($notify){
        $sign = $notify['sign'];
        $data = 'notify_data=' . $notify['notify_data'];
        $alipay_public_key_url = ROOT_PATH . '/data/alipay_public_key.pem';
        $pubKey = file_get_contents($alipay_public_key_url);
        $res = openssl_get_publickey($pubKey);
        $result = (bool) openssl_verify($data,base64_decode($sign),$res);
        //日志,调试完成可删除
//        set_logs('mobile123',tcz_json_encode(array(
//            'data' => $data,
//            'sign' => $sign
//        )));
        openssl_free_key($res);
        return $result;
    }

    /* 返回通知结果 */
    function verify_notify_mobile($notify,$paysign,$strict = false){
        /* 验证来路是否可信 */
        if($strict){
            /* 严格验证 */
            $verify_result = $this->_query_notify($notify['notify_id']);
            if(!$verify_result){
                /* 来路不可信 */
                $this->_error('notify_unauthentic');
                return false;
            }
        }
        /* 验证通知是否可信 */

        $sign_result = $this->_verify_sign_mobile($notify);
        //$sign_result = true;  2012-12-25 chubin 注释
        if(!$sign_result){
            /* 若本地签名与网关签名不一致，说明签名不可信 */
            $this->_error('sign_inconsistent');
            return false;
        }

        if($paysign['out_order_sn'] != $notify['out_trade_no']){
            /* 通知中的订单与欲改变的订单不一致 */
            $this->_error('order_inconsistent');
            return false;
        }
        if($paysign['money'] != $notify['total_fee']){
            /* 支付的金额与实际金额不一致 */
            $this->_error('price_inconsistent');
            return false;
        }
        return true;
    }

}

?>